#pragma once

#ifndef __PARSING_PARSER_H
#define __PARSING_PARSER_H

#include "Objects.h"

namespace Canvas
{
	namespace Parsing
	{
		struct TextPos 
		{
			static const int UnknownValue = -2;
			int index;
			int row;
			int col;
			TextPos(int i, int r, int c): index(i), row(r), col(c) {}
			TextPos(int r, int c): TextPos(UnknownValue, r, c) {}
			TextPos(int i) : TextPos(i, UnknownValue, UnknownValue) {}
			TextPos() : TextPos(UnknownValue) {}

			static int Compare(const TextPos& a, const TextPos& b)
			{
				if (a.index != UnknownValue && b.index != UnknownValue)
				{
					return a.index - b.index;
				}
				else if (a.row != UnknownValue && b.row != UnknownValue
					&& a.col != UnknownValue && b.col != UnknownValue)
				{
					if (a.row == b.row)
						return a.col - b.col;
					return a.row - b.row;
				}
				else
				{
					return 0;
				}
			}

			bool operator==(const TextPos& pos) const { return Compare(*this, pos) == 0; }

			bool operator!=(const TextPos& pos) const { return Compare(*this, pos) != 0; }
			bool operator<(const TextPos& pos) const { return Compare(*this, pos)<0; }
			bool operator<=(const TextPos& pos) const { return Compare(*this, pos) <= 0; }
			bool operator>(const TextPos& pos) const { return Compare(*this, pos)>0; }
			bool operator>=(const TextPos& pos) const { return Compare(*this, pos) >= 0; }
		};

		struct TextRange
		{
			TextPos start;
			TextPos end;
			int codeIndex;

			TextRange(TextPos _start, TextPos _end, int index = -1):
				start(_start), end(_end), codeIndex(index) {}
			TextRange(int index):
				TextRange(TextPos{}, TextPos{}) 
			{
				end.col = -1;
				end.index = -1;
			}

			bool operator==(const TextRange& range) const { return start == range.start && end == range.end; }
			bool operator!=(const TextRange& range) const { return start != range.start || end != range.end; }
			bool Contains(const TextPos& pos) const { return start <= pos && pos <= end; }
			bool Contains(const TextRange& range) const { return start <= range.start && range.end <= end; }
		};

		class ParsingTreeNode;
		class ParsingTreeToken;
		class ParsingTreeObject;
		class ParsingTreeArray;

		using Canvas::Base::Object;

		class ParsingTreeNode : public Object
		{
		public:
			class IVisitor
		};
	}
}	

#endif // __PARSING_PARSER_H